package models

import (
"api/app/{{ table.path }}/auto/v1/mc"
"api/libs/orm"
"gitee.com/dreamwood/ez"
{% if model == "tree" %}

    "context"
    "errors"
    "api/libs/errs"
    "fmt"
{% endif %}
)

func (this {{ table.name }}) TableName() string {
return "{{ table.path }}_{{ table.name | snake }}"
}

func (this {{ table.name }}) MakeChoice() ez.M {
return ez.M{"value": this.Id, "label": this.Id}
}

func init() {
conf := mc.Get{{ table.name }}EzConfig()
conf.Crud["default"] = orm.EzModelFieldLimitation{
Select:    []string{}, //snake写法，多对一应该写xxx_id,关联关系不应该写在这里，使用Relations配置项
Omit:      []string{}, //select优先级高于Omit,如果select和omit同时设置了，omit不生效
Relations: []string{}, //大驼峰写法
}
{% if model == "tree" %}
conf.Crud["lr"] = orm.EzModelFieldLimitation{
Select:    []string{"l", "r", "link", "level"}, //snake写法，多对一应该写xxx_id,关联关系不应该写在这里，使用Relations配置项
Omit:      []string{},                          //select优先级高于Omit,如果select和omit同时设置了，omit不生效
Relations: []string{},
}
{% endif %}
}

{% if model == "tree" %}

    type {{ table.name }}TreeModel struct {}

    func (this {{ table.name }}TreeModel) UpdateLeftAndRight(rootId int, count int, level int) int {
    crud := New{{ table.name }}Crud()
    sons,e := crud.FindBy(ez.M{"parentId": rootId}, []string{"sort"}, 0, 0)
    count++
    if e != nil {
    return count
    }
    if len(sons) == 0 {
    return count
    }
    for _, son := range sons {
    son.Level = level
    link, isCircle := this.GetParents(son.Id)
    if isCircle {
    ez.PrintError(errors.New("闭环循环"))
    }
    son.Link = link
    son.L = count
    son.Save()
    //进入子分类继续
    son.R = this.UpdateLeftAndRight(son.Id, count, level+1)
    count = son.R
    son.Save()
    count++
    }
    return count
    }

    func (this {{ table.name }}TreeModel) ClearDirtyParent() {
    crud := New{{ table.name }}Crud()
    all, e := crud.FindBy(ez.M{}, nil, 0, 0)
    if errs.Try(e) {
    return
    }
    ids := make([]int, 0)
    for _, row := range all {
    ids = append(ids, row.Id)
    }
    missed, e := crud.FindBy(ez.M{"parentId__nin": ids}, nil, 0, 0)
    for _, item := range missed {
    item.ParentId = 0
    item.Save()
    }
    }

    // 获取父级元素，检测闭环
    func (this {{ table.name }}TreeModel) GetParents(curId int) (link string, isCircled bool) {
    crud := New{{ table.name }}Crud()
    cur, e := crud.Find(curId)
    if e != nil {
    errs.Get(e)
    return
    }
    //闭环检测
    log := make(map[int]bool)
    for {
    if cur.ParentId == 0 {
    return link, isCircled //没有闭环
    }
    parent, e := crud.Find(cur.ParentId)
    if e != nil {
    errs.Get(e)
    return
    }
    if parent == nil {
    return link, isCircled //没有闭环
    }
    //检测到闭环 就直接退出
    logFind, ok := log[parent.Id]
    if ok && logFind {
    isCircled = true
    return link, isCircled
    }
    link = fmt.Sprintf("%d_%s", parent.L, link)
    log[parent.Id] = true
    cur = parent
    }
    }

    // 绑定一个事件监听
    func init() {
    ez.ListenJoin(mc.{{ table.name }}EventAfterSave, func(v interface{}, ctx context.Context) {
    _, ok := v.(*{{ table.name }})
    if ok {
    {{ table.name }}TreeModel{}.UpdateLeftAndRight(0, 0, 0)
    }
    })
    }
{% endif %}